home *** CD-ROM | disk | FTP | other *** search
- /* Ilbm.library C application, PicInfo.c:
-
- Set your editor's TAB width to 3
-
- cc +p IFFinfo.c
- as -cd IlbmInterface.asm
- ln -o IFFinfo IFFinfo.o IlbmInterface.o -lcl32
-
- This program can only be run from the CLI. It takes 1 arg, the name of a
- file. This program will then print information about the file. For ILBMs and
- ANIMs, it will print out information from the BHMD(s) such as image width,
- height, depth, etc. For other IFF files, it will simply print the chunk IDs
- as it encounters them. For ANIMs, it will total the number of "frames"
- (ILBMs) in the file. Note that the library automatically dives into LISTS
- and CATS on our behalf. We don't even have to know that we are inside of a
- LIST or CAT.
-
- This is an example of using the library's mid-level routine LoadILBM() with
- our own FORM and PROP handlers instead of lib's default routines. This is the
- way to go if you need an ANIM reader or some non-ILBM reader/writer. Note
- that if our FORMHandler wasn't interested in ILBMs or ANIMs, we wouldn't need
- an ILBMFrame, and would use LoadIFF() instead of LoadILBM().
-
- */
-
- #include "math.h"
- #include "functions.h" /* Manx C declarations */
-
- #include "exec/tasks.h"
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "libraries/dos.h"
- #include "libraries/dosextens.h"
-
- /* The ilbm lib C INCLUDE file */
- #include "ILBM_Lib.h"
-
-
- /*-------------------------------defines---------------------------------*/
-
- IFFP myForm();
- IFFP myProp();
-
- /* Data for the Dissidents ILBM library */
- struct ILBMBase *ILBMBase=0L;
- ILBMFrame myILBMFrame; /* Whenever we plan on parsing an ILBM
- or ANIM, we need an ILBMFrame */
- /* Data for our program */
- struct FileHandle *fp = 0;
- SHORT numFrames = -1; /* To count the # of frames in an ANIM */
- UBYTE handled_anim = 0; /* To tell main() that we found an ANIM */
-
- /*------------------------------start of main()----------------------------*/
-
- main( argc, argv )
- LONG argc;
- UBYTE *argv[];
- {
- IFFP Result;
- /* LoadILBM() and LoadIFF() need a Vectors structure */
- Vectors myVectors;
-
- /* We expect the filename for the first arg. */
- if( argc != 2 )
- {
- printf("USAGE: IFFinfo filename\n");
- exit();
- }
-
- /* Open the ILBM lib */
- if( (ILBMBase=(struct ILBMBase *)OpenLibrary("ilbm.library", 0L)) == NULL )
- {
- printf("Need the dissidents ilbm.library on boot disk\n");
- exit();
- }
-
- /* Note that we are using the lib's middle level functions so that we can
- install our own handlers for each encountered group and context. Also,
- we can parse any IFF FORM, not just ILBMs and ANIMs using this level.
- Unlike the lib's high level ILBM functions LoadIFFToWindow() and
- SaveWindowToIFF(), the mid level functions don't open the IFF file for us.
- We are going to install our own function, myForm(), as the routine
- which the library calls whenever it encounters a FORM ID. Our function,
- myProp() will be called for non-ILBM PROPS. (Remember, the library
- automatically handles all ILBM PROPS by parsing info into a PropILBMFrame.)
- We "install" these routines by setting up the appropriate fields in our
- Vectors structure. Let's do all this now. */
-
- /* Open the IFF File */
- fp = Open( argv[1], MODE_OLDFILE );
-
- if (fp)
- {
-
- /* Setup the Vectors structure. (i.e. "install" myForm() and myProp()) */
- myVectors.PROPhandler = myProp;
- myVectors.FORMhandler = myForm;
- myVectors.CHUNKhandler = 0;
- myVectors.NonILBMhandler = 0;
- /* Don't care about CHUNKhandler or NonILBMhandler as long as we have
- our own FORMhandler. */
-
- myILBMFrame.iUserFlags=0;
-
- /* Start parsing the file */
- Result=LoadILBM( fp, &myVectors, &myILBMFrame );
-
- /* O.K. we're back. Did we successfully parse as much as we wanted?
- Well, our FORM routine should have returned IFF_OKAY if we parsed
- the entire file. Otherwise, myForm, myProp, or an internal library
- routine knocked us out by returning some other IFFP error code. Let's
- get an informative error msg to display.
- */
-
- /* If some error, get the IFFP error message and print it */
- if( Result != IFF_OKAY )
- {
- puts( GetIFFPMsg( Result ) );
- }
- else /* If it was an ANIM we inspected, show the # of frames */
- {
- if( handled_anim )
- printf("Number of Frames = %d", numFrames+1);
- }
-
- /* Close the IFF File */
- Close(fp);
-
- }
- else printf( "Couldn't open %s. \n", argv[1]);
-
- printf("\n");
-
- /* Close ILBM lib */
- if( ILBMBase ) CloseLibrary( ILBMBase );
- exit();
- } /* end of main() */
-
-
- /*========= LoadILBM() or LoadIFF() calls me when it finds a FORM ==========*/
-
- IFFP myForm( chunkID, context, vectors, frame, proplist )
- PROPList *proplist;
- ILBMFrame *frame;
- Vectors *vectors;
- GroupContext *context;
- ID chunkID;
- {
- register IFFP code = IFF_OKAY;
- register ULONG propf;
- BitMapHeader bmhdr;
-
- /* Print the FORM ID */
- printf("========= FORM %c%c%c%c =========\n",
- (char) ((chunkID>>24L) & 0x7F),
- (char) ((chunkID>>16L) & 0x7F),
- (char) ((chunkID>>8) & 0x7F),
- (char) (chunkID & 0x7F) );
-
- /* --------------------- ANIM HEADER ------------------------- */
-
- /* If an ANIM, reset our frame count and ANIM flags of iUserFlags.
- Then parse the "frames" (imbedded ILBMs) of the ANIM. Note that
- GetF1ChunkHdr actually calls our myForm() routine for each imbedded
- ILBM "frame of animation" (i.e. this function is recursive). */
-
- if (chunkID == ID_ANIM)
- {
- /* set ANIMFLAG of iUserFlags to indicate that we're in an ANIM */
- frame->iUserFlags |= ANIMFLAG;
-
- /* clear HANDLED_ANIM to indicate that we aren't successful yet */
- handled_anim = 0;
-
- numFrames = -1; /* first frame number will be 0 */
-
- /* Parse each frame of the ANIM */
- while (code >= 0)
- {
- code = GetF1ChunkHdr(context);
- }
-
- /* If we didn't get END_MARK back, then an error */
- if (code == END_MARK)
- {
- /* set HANDLED_ANIM to indicate that we successfully handled the ANIM */
- handled_anim = 1;
-
- code = IFF_OKAY; /* So that we continue parsing any more FORMs in
- the file */
- }
- }
-
- /* ---------------------- ILBM FORMS (ANIM "frames") -------------------- */
-
- if (chunkID == ID_ILBM )
- {
- /* Parse an ILBM or an ANIM "frame" (which is also an ILBM) */
-
- /* If there was an ILBM PROP for this group, copy the PROPFrame to our
- ILBMFrame.
- Note: SearchPROP() can return any kind of frame. Here, it is an
- ILBMFrame since chunkID == ID_ILBM. If we needed to reference
- anything in the returned pointer, we would have to recast it as
- an (ILBMFrame *).
- */
- if( !(propf = SearchPROP( chunkID, proplist )) )
- CopyILBMProp( propf, frame );
-
- if( frame->iUserFlags & ANIMFLAG )
- {
- ++numFrames; /* 1 more "frame" */
- printf( "--- Frame #%d ---\n", numFrames+1 );
- }
-
- while( code >= 0 ) /* Negative numbers are errors, 0 means "ok, continue"
- and positive numbers are IFF chunk IDs
- */
-
- {
- /* Move to the start of the next chunk */
- code = GetFChunkHdr( context );
-
- if (code > 0 )
- /* Here's a chunk ID. If this were a REAL program, we'd probably
- check to see if this is a chunk that we want to parse. If so, we
- could get the chunksize from the context structure, read the chunk
- into memory, and do something with the data. For example, like
- what I did with the BMHD chunk. Or maybe like this:
- bytes = ChunkMoreBytes( context );
- if( !( memptr = AllocMem( bytes, 0L ) ))
- {
- code = IFFReadBytes( bytes, context, memptr );
- }
-
- */
- {
- printf(" %c%c%c%c\n",
- (char) ( (code>>24L) & 0x7F),
- (char) ( (code>>16L) & 0x7F),
- (char) ( (code>>8) & 0x7F),
- (char) ( code & 0x7F) );
-
- if( code == ID_BMHD )
- {
- /* Print out info about the image */
- code = GetBMHD(context, &bmhdr);
- if( code == IFF_OKAY )
- {
- printf(" width=%d, height=%d, depth=%d\n",
- bmhdr.w, bmhdr.h, bmhdr.nPlanes);
- }
- }
-
- }
- }
- }
-
- /* --------------------- Non-ILBM FORMS --------------------- */
- else
- {
- /* A REAL program would normally search the PROPList for any frames
- of the same type, and if found extract needed info from it.
- See notes in myProp() */
-
- while( code >= 0 )
- {
- code = GetF1ChunkHdr(context);
-
- if (code > 0)
- /* Here's a chunk ID. If this were a REAL program, we'd probably
- do something useful with it.
- */
- {
- printf(" %c%c%c%c\n",
- (char) ( (code>>24L) & 0x7F),
- (char) ( (code>>16L) & 0x7F),
- (char) ( (code>>8) & 0x7F),
- (char) ( code & 0x7F) );
- }
- }
- }
-
- /*
- As long as we rtn IFF_OKAY, the library will continue parsing the IFF
- file (until it gets to the end). If we rtn any other value, the library will
- return us back to main() from LoadILBM() with that value. For example, if
- we return IFF_DONE, we would return from LoadILBM with IFF_DONE.
-
- Note: the library routines GetFChunkHdr and GetF1ChunkHdr will return
- END_MARK when there's no more chunks in this FORM. In that case, we should
- know whether we found what we wanted in this FORM. If we did, we return
- IFF_OKAY to continue parsing the next FORM (we may be inside of a LIST or
- CAT), or IFF_DONE if we want to get out with what we've got. If we didn't
- find what we want, we would return IFF_OKAY to continue parsing.
-
- In this example, we're looking for everything, so we always return IFF_OKAY
- when GetFChunkHdr or GetF1ChunkHdr returns END_MARK.
- */
-
- if (code == END_MARK)
- {
- /* Print a double-spaced line inbetween forms */
- puts("=============================\n");
- code = IFF_OKAY;
- }
-
- return( code );
- }
-
-
- /*========= LoadILBM() or LoadIFF() calls me when it finds a PROP ==========*/
-
- IFFP myProp( chunkID, propID, context, vectors, frame, proplist )
- PROPList *proplist;
- ILBMFrame *frame;
- Vectors *vectors;
- GroupContext *context;
- ID propID;
- ID chunkID;
- {
- /* We only hear about non-ILBM PROPS. If this were a REAL program, we
- would probably allocate some PROPFrame that we defined for the passed
- propID (an SMUSPropFrame for an ID_SMUS maybe?). Then we would
- parse the PROP's chunks just like in the FORMhandler, storing info in
- this new PROPFrame. Later, in our FORMHandler, we search the PROPList
- for the appropriate ID and retrieve the info. The library automatically
- updates the PROPList when it gets to the end of an IFF group so that you
- don't have to keep track of which level you're at and which PROPS affect
- which chunks. Also, the library frees all PROPFrames that you allocate
- with GetPROPStruct() by the time we return to main. */
-
- /* Print the PROP ID */
- printf(" PROP %c%c%c%c\n",
- (char) ((chunkID>>24L) & 0x7F),
- (char) ((chunkID>>16L) & 0x7F),
- (char) ((chunkID>>8) & 0x7F),
- (char) (chunkID & 0x7F) );
-
- return( IFF_OKAY );
- }
-